package xutil

import (
	"bytes"
	"crypto/sha1"
	"encoding/base64"
	"io"
	"mime/multipart"
	"os"
	/* 	"github.com/qiniu/go-sdk/v7/auth"
	   	"github.com/qiniu/go-sdk/v7/auth/qbox"
	   	"github.com/qiniu/go-sdk/v7/storage" */)

/*
type Qiniu struct {
	Ak  string
	Sk  string
	Mac *auth.Credentials
}

func F新建七牛云(ak, sk string) *Qiniu {
	mac := qbox.NewMac(ak, sk)
	return &Qiniu{Ak: ak, Sk: sk, Mac: mac}
}

func (a *Qiniu) F上传字节数据文件(token, key string, data []byte) (err error) {
	cfg := storage.Config{
		UseHTTPS:      false,
		UseCdnDomains: false,
	}
	// 上传是否使用CDN上传加速

	formUploader := storage.NewResumeUploaderV2(&cfg)

	ret := storage.PutRet{}
	putExtra := storage.RputV2Extra{
		CustomVars: map[string]string{},
	}
	size := int64(len(data))
	err = formUploader.Put(context.Background(), &ret, token, key, bytes.NewReader(data), size, &putExtra)

	return
}

// args第一个是文件的路径,第二个是bucket,第三个是回调地址,第四个是回调能数
func (a *Qiniu) F获取前端直传凭证(args ...string) (tk string, err error) {
	putPolicy := storage.PutPolicy{
		Scope:            fmt.Sprintf("%s:%s", args[1], args[0]),
		CallbackBodyType: "application/json",
		CallbackBody:     `{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)"}`,
	}
	//如果有三个参数，那么就是加回调地址
	if len(args) > 2 && args[2] != "" {
		putPolicy.CallbackURL = args[2]
	}
	if len(args) > 3 && args[3] != "" {
		putPolicy.CallbackBody = args[3]
	}
	tk = putPolicy.UploadToken(a.Mac)
	return
}

func (a *Qiniu) F路径上传文件(token, key, path string) (err error) {
	cfg := storage.Config{
		Region:        &storage.ZoneHuadong,
		UseHTTPS:      true,
		UseCdnDomains: false,
	}
	// 上传是否使用CDN上传加速

	formUploader := storage.NewResumeUploaderV2(&cfg)

	ret := storage.PutRet{}
	putExtra := storage.RputV2Extra{
		CustomVars: map[string]string{},
	}
	err = formUploader.PutFile(context.Background(), &ret, token, key, path, &putExtra)
	return
}

// 获取上传凭证
func (a *Qiniu) F获取上传凭证(bucket string) (token string) {
	putPolicy := storage.PutPolicy{
		Scope: bucket,
	}
	token = putPolicy.UploadToken(a.Mac)
	return
}

func (a *Qiniu) F获取访问凭证(domain, key string, ti ...int64) (url string) {
	deadline := time.Now().Add(time.Second * 3600).Unix() //1小时有效期
	if len(ti) != 0 {
		deadline = time.Now().Add(time.Second * time.Duration(ti[0]*3600)).Unix() //1小时有效期
	}
	url = storage.MakePrivateURL(a.Mac, domain, key, deadline)
	return
}

func (a *Qiniu) F删除文件(bucket, key string) (err error) {
	cfg := storage.Config{
		UseHTTPS: true,
	}
	bucketManager := storage.NewBucketManager(a.Mac, &cfg)
	err = bucketManager.Delete(bucket, key)
	return
} */

const (
	BLOCK_BITS = 22 // Indicate that the blocksize is 4M
	BLOCK_SIZE = 1 << BLOCK_BITS
)

func 区块统计(fsize int64) int {
	return int((fsize + (BLOCK_SIZE - 1)) >> BLOCK_BITS)
}

func F获取文件路径的etag(path string) (etag string, err error) {
	f, err := os.Open(path)
	if err != nil {
		return
	}
	defer f.Close()
	fi, err := f.Stat()
	if err != nil {
		return
	}
	return F获取七牛云etag(f, fi.Size())
}

func F获取前端文件etag(file *multipart.FileHeader) (etag string, err error) {
	f, err := file.Open()
	if err != nil {
		return
	}
	defer f.Close()
	return F获取七牛云etag(f, file.Size)
}

func 获取哈希1(b []byte, r io.Reader) ([]byte, error) {
	h := sha1.New()
	_, err := io.Copy(h, r)
	if err != nil {
		return nil, err
	}
	return h.Sum(b), nil
}

// 可以是file.Open()
func F获取七牛云etag(r io.Reader, fsize int64) (etag string, err error) {
	区块数 := 区块统计(fsize)
	sha1Buf := make([]byte, 0, 21)
	if 区块数 <= 1 { // file size <= 4M
		sha1Buf = append(sha1Buf, 0x16)
		sha1Buf, err = 获取哈希1(sha1Buf, r)
		if err != nil {
			return
		}
	} else { // file size > 4M
		sha1Buf = append(sha1Buf, 0x96)
		sha1BlockBuf := make([]byte, 0, 区块数*20)
		for i := 0; i < 区块数; i++ {
			body := io.LimitReader(r, BLOCK_SIZE)
			sha1BlockBuf, err = 获取哈希1(sha1BlockBuf, body)
			if err != nil {
				return
			}
		}
		sha1Buf, _ = 获取哈希1(sha1Buf, bytes.NewReader(sha1BlockBuf))
	}
	etag = base64.URLEncoding.EncodeToString(sha1Buf)
	return
}
